package com.nageoffer.shortlink.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nageoffer.shortlink.admin.common.biz.user.UserContext;
import com.nageoffer.shortlink.admin.common.convention.result.Result;
import com.nageoffer.shortlink.admin.dao.entity.GroupDo;
import com.nageoffer.shortlink.admin.dao.mapper.GroupMapper;
import com.nageoffer.shortlink.admin.dto.req.ShortLinkGroupSortReqDTO;
import com.nageoffer.shortlink.admin.dto.req.ShortLinkGroupUpdateReqDTO;
import com.nageoffer.shortlink.admin.dto.resp.ShortLinkGroupRespDTO;
import com.nageoffer.shortlink.admin.remote.dto.ShortLinkRemoteService;
import com.nageoffer.shortlink.admin.remote.dto.resp.ShortLinkCountQueryReqDTO;
import com.nageoffer.shortlink.admin.service.GroupService;
import com.nageoffer.shortlink.admin.util.RandomStringGenerator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 短链接分组接口实现层
 */
@Service
@Slf4j
public class GroupServiceImpl extends ServiceImpl<GroupMapper, GroupDo> implements GroupService {

    ShortLinkRemoteService shortLinkRemoteService = new ShortLinkRemoteService() {
    };


    /**
     * 新增分组
     * @param groupName
     */
    @Override
    public void saveGroup(String groupName) {
        this.saveGroup(UserContext.getUsername(),groupName);

    }

    @Override
    public void saveGroup(String userName, String groupName) {
        String gid;
        do {
            gid = RandomStringGenerator.generateRandomString();
        }while(!hasGid(userName,gid));
        GroupDo build = GroupDo.builder()
                .gid(gid)
                .sortOrder(0)
                .username(userName)
                .name(groupName)
                .build();
        baseMapper.insert(build);
    }


    /**
     * 查询分组
     * @return
     */
    @Override
    public List<ShortLinkGroupRespDTO> listGroup() {
        // 1. 查询当前用户的短链接分组（原逻辑不变，确保基础数据正确）
        LambdaQueryWrapper<GroupDo> queryWrapper = Wrappers.lambdaQuery(GroupDo.class)
                .eq(GroupDo::getDelFlag, 0)
                .eq(GroupDo::getUsername, UserContext.getUsername())
                .orderByDesc(GroupDo::getSortOrder, GroupDo::getUpdateTime);
        List<GroupDo> groupDos = baseMapper.selectList(queryWrapper);
        // 若分组为空，直接返回空列表（避免后续无意义的远程调用）
        if (CollectionUtils.isEmpty(groupDos)) {
            return Collections.emptyList();
        }

        // 2. 远程调用查询分组的短链接数量（增加异常处理+null安全）
        List<String> groupIds = groupDos.stream().map(GroupDo::getGid).toList();
        List<ShortLinkCountQueryReqDTO> countList = Collections.emptyList(); // 默认空列表
        try {
            Result<List<ShortLinkCountQueryReqDTO>> listResult = shortLinkRemoteService.listGroupShortLinkCount(groupIds);
            // 关键：判断Result是否成功 + data是否为null，避免空指针
            if (listResult != null && listResult.isSuccess() && listResult.getData() != null) {
                countList = listResult.getData();
            }
        } catch (Exception e) {
            // 远程调用异常处理（根据业务选择：打日志/返回默认值/抛自定义异常）
            log.error("查询短链接分组数量远程调用失败，分组ID列表：{}", groupIds, e);
            // 此处不抛异常，避免因远程服务问题导致分组列表查询整体失败（业务容错）
        }

        // 3. 拷贝分组数据到响应DTO（原逻辑不变）
        List<ShortLinkGroupRespDTO> groupRespList = BeanUtil.copyToList(groupDos, ShortLinkGroupRespDTO.class);

        // 4. 给响应DTO设置短链接数量（null安全+简化代码）
        List<ShortLinkCountQueryReqDTO> finalCountList = countList;
        groupRespList.forEach(respDTO -> {
            // 从countList中匹配当前分组的数量（countList已确保非null，可安全stream）
            finalCountList.stream()
                    .filter(countDTO -> Objects.equals(countDTO.getGid(), respDTO.getGid()))
                    .findFirst()
                    // 简化：直接用匹配到的countDTO设置数量，避免冗余的first.get()
                    .ifPresent(countDTO -> respDTO.setShortLinkCount(countDTO.getShortLinkCount()));
        });

        return groupRespList;
    }

    /**
     * 修改分组
     * @param shortLinkGroupUpdateReqDTO
     */
    @Override
    public void updateGroup(ShortLinkGroupUpdateReqDTO shortLinkGroupUpdateReqDTO) {
        LambdaUpdateWrapper<GroupDo> eq = Wrappers.lambdaUpdate(GroupDo.class)
                .eq(GroupDo::getUsername, UserContext.getUsername())
                .eq(GroupDo::getGid, shortLinkGroupUpdateReqDTO.getGid())
                .eq(GroupDo::getDelFlag,0);
        GroupDo groupDo = new GroupDo();
        groupDo.setName(shortLinkGroupUpdateReqDTO.getName());
        log.info("修改的对象为：{}",groupDo);
        baseMapper.update(groupDo,eq);


    }

    /**
     * 删除分组
     * @param gid
     */
    @Override
    public void deleteGroup(String gid) {
        LambdaUpdateWrapper<GroupDo> eq = Wrappers.lambdaUpdate(GroupDo.class)
                .eq(GroupDo::getUsername, UserContext.getUsername())
                .eq(GroupDo::getGid, gid)
                .eq(GroupDo::getDelFlag,0);
        GroupDo groupDo = new GroupDo();
        groupDo.setDelFlag(1);
        baseMapper.update(groupDo,eq);

    }

    @Override
    public void sortGroup(List<ShortLinkGroupSortReqDTO> sortReqDTOS) {
        sortReqDTOS.forEach(each->{
            GroupDo groupDo = GroupDo.builder()
                    .gid(each.getGid())
                    .sortOrder(each.getSortOrder())
                    .build();
            LambdaUpdateWrapper<GroupDo> eq = Wrappers.lambdaUpdate(GroupDo.class)
                    .eq(GroupDo::getUsername, UserContext.getUsername())
                    .eq(GroupDo::getGid, each.getGid())
                    .eq(GroupDo::getDelFlag, 0);
            baseMapper.update(groupDo,eq);
        });
    }

    /**
     * 判断gid是否存在
     * @param gid
     * @return
     */
    private Boolean hasGid(String  username,String gid){
        LambdaQueryWrapper<GroupDo> eq = Wrappers.lambdaQuery(GroupDo.class)
                .eq(GroupDo::getGid, gid)
                .eq(GroupDo::getUsername,Optional.ofNullable(username).orElse(UserContext.getUsername()));
        GroupDo groupDo = baseMapper.selectOne(eq);
        return groupDo==null;

    }

}
